package com.retail.user.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.retail.user.dto.UserCreateDTO;
import com.retail.user.dto.UserQueryDTO;
import com.retail.user.dto.UserUpdateDTO;
import com.retail.user.dto.UserVO;
import com.retail.user.entity.User;
import com.retail.user.entity.UserRole;
import com.retail.user.mapper.UserMapper;
import com.retail.user.mapper.UserRoleMapper;
import com.retail.user.service.UserService;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;

import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;

/**
 * 用户服务实现类
 * 
 * @author retail-platform
 * @since 2024-09-25
 */
@Slf4j
@Service
@RequiredArgsConstructor
public class UserServiceImpl implements UserService {

    private final UserMapper userMapper;
    private final UserRoleMapper userRoleMapper;
    private final PasswordEncoder passwordEncoder;

    @Override
    public IPage<UserVO> getUserPage(UserQueryDTO queryDTO) {
        log.info("分页查询用户列表，查询条件：{}", queryDTO);
        
        Page<UserVO> page = new Page<>(queryDTO.getPageNum(), queryDTO.getPageSize());
        IPage<UserVO> result = userMapper.selectUserPage(page, queryDTO);
        
        log.info("分页查询用户列表完成，总数：{}", result.getTotal());
        return result;
    }

    @Override
    public UserVO getUserById(Long userId) {
        log.info("根据用户ID查询用户详情，用户ID：{}", userId);
        
        UserVO userVO = userMapper.selectUserWithRoles(userId);
        
        log.info("根据用户ID查询用户详情完成，用户：{}", userVO);
        return userVO;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Long createUser(UserCreateDTO createDTO) {
        log.info("创建用户，用户信息：{}", createDTO);
        
        // 检查用户名是否已存在
        if (isUsernameExists(createDTO.getUsername(), null)) {
            throw new RuntimeException("用户名已存在");
        }
        
        // 检查邮箱是否已存在
        if (createDTO.getEmail() != null && isEmailExists(createDTO.getEmail(), null)) {
            throw new RuntimeException("邮箱已存在");
        }
        
        // 检查手机号是否已存在
        if (createDTO.getPhone() != null && isPhoneExists(createDTO.getPhone(), null)) {
            throw new RuntimeException("手机号已存在");
        }
        
        // 创建用户
        User user = new User();
        BeanUtils.copyProperties(createDTO, user);
        user.setPassword(passwordEncoder.encode(createDTO.getPassword()));
        user.setCreateTime(LocalDateTime.now());
        user.setUpdateTime(LocalDateTime.now());
        
        int result = userMapper.insert(user);
        if (result <= 0) {
            throw new RuntimeException("创建用户失败");
        }
        
        // 分配角色
        if (!CollectionUtils.isEmpty(createDTO.getRoleIds())) {
            List<UserRole> userRoles = new ArrayList<>();
            for (Long roleId : createDTO.getRoleIds()) {
                UserRole userRole = new UserRole();
                userRole.setUserId(user.getId());
                userRole.setRoleId(roleId);
                userRole.setCreateTime(LocalDateTime.now());
                userRole.setUpdateTime(LocalDateTime.now());
                userRoles.add(userRole);
            }
            userRoleMapper.batchInsert(userRoles);
        }
        
        log.info("创建用户成功，用户ID：{}", user.getId());
        return user.getId();
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean updateUser(UserUpdateDTO updateDTO) {
        log.info("更新用户，用户信息：{}", updateDTO);
        
        // 检查用户是否存在
        User existingUser = userMapper.selectById(updateDTO.getId());
        if (existingUser == null) {
            throw new RuntimeException("用户不存在");
        }
        
        // 检查邮箱是否已被其他用户使用
        if (updateDTO.getEmail() != null && isEmailExists(updateDTO.getEmail(), updateDTO.getId())) {
            throw new RuntimeException("邮箱已被其他用户使用");
        }
        
        // 检查手机号是否已被其他用户使用
        if (updateDTO.getPhone() != null && isPhoneExists(updateDTO.getPhone(), updateDTO.getId())) {
            throw new RuntimeException("手机号已被其他用户使用");
        }
        
        // 更新用户信息
        User user = new User();
        BeanUtils.copyProperties(updateDTO, user);
        user.setUpdateTime(LocalDateTime.now());
        
        int result = userMapper.updateById(user);
        if (result <= 0) {
            throw new RuntimeException("更新用户失败");
        }
        
        // 更新用户角色
        if (updateDTO.getRoleIds() != null) {
            // 删除原有角色关联
            userRoleMapper.deleteByUserId(updateDTO.getId());
            
            // 添加新角色关联
            if (!CollectionUtils.isEmpty(updateDTO.getRoleIds())) {
                List<UserRole> userRoles = new ArrayList<>();
                for (Long roleId : updateDTO.getRoleIds()) {
                    UserRole userRole = new UserRole();
                    userRole.setUserId(updateDTO.getId());
                    userRole.setRoleId(roleId);
                    userRole.setCreateTime(LocalDateTime.now());
                    userRole.setUpdateTime(LocalDateTime.now());
                    userRoles.add(userRole);
                }
                userRoleMapper.batchInsert(userRoles);
            }
        }
        
        log.info("更新用户成功，用户ID：{}", updateDTO.getId());
        return true;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean deleteUser(Long userId) {
        log.info("删除用户，用户ID：{}", userId);
        
        // 检查用户是否存在
        User user = userMapper.selectById(userId);
        if (user == null) {
            throw new RuntimeException("用户不存在");
        }
        
        // 删除用户角色关联
        userRoleMapper.deleteByUserId(userId);
        
        // 删除用户
        int result = userMapper.deleteById(userId);
        
        log.info("删除用户完成，用户ID：{}，结果：{}", userId, result > 0);
        return result > 0;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean resetPassword(Long userId, String newPassword) {
        log.info("重置用户密码，用户ID：{}", userId);
        
        // 检查用户是否存在
        User user = userMapper.selectById(userId);
        if (user == null) {
            throw new RuntimeException("用户不存在");
        }
        
        // 更新密码
        User updateUser = new User();
        updateUser.setId(userId);
        updateUser.setPassword(passwordEncoder.encode(newPassword));
        updateUser.setUpdateTime(LocalDateTime.now());
        
        int result = userMapper.updateById(updateUser);
        
        log.info("重置用户密码完成，用户ID：{}，结果：{}", userId, result > 0);
        return result > 0;
    }

    @Override
    public User getUserByUsername(String username) {
        List<User> users = userMapper.selectByUsername(username);
        if (users.isEmpty()) {
            return null;
        }
        if (users.size() > 1) {
            log.warn("发现重复用户名：{}，共{}条记录", username, users.size());
        }
        return users.get(0);
    }

    @Override
    public User getUserByEmail(String email) {
        return userMapper.selectByEmail(email);
    }

    @Override
    public User getUserByPhone(String phone) {
        return userMapper.selectByPhone(phone);
    }

    @Override
    public boolean isUsernameExists(String username, Long excludeUserId) {
        LambdaQueryWrapper<User> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(User::getUsername, username);
        if (excludeUserId != null) {
            wrapper.ne(User::getId, excludeUserId);
        }
        return userMapper.selectCount(wrapper) > 0;
    }

    @Override
    public boolean isEmailExists(String email, Long excludeUserId) {
        LambdaQueryWrapper<User> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(User::getEmail, email);
        if (excludeUserId != null) {
            wrapper.ne(User::getId, excludeUserId);
        }
        return userMapper.selectCount(wrapper) > 0;
    }

    @Override
    public boolean isPhoneExists(String phone, Long excludeUserId) {
        LambdaQueryWrapper<User> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(User::getPhone, phone);
        if (excludeUserId != null) {
            wrapper.ne(User::getId, excludeUserId);
        }
        return userMapper.selectCount(wrapper) > 0;
    }

    @Override
    public boolean updateLastLoginInfo(Long userId, String loginIp) {
        log.info("更新用户最后登录信息，用户ID：{}，登录IP：{}", userId, loginIp);
        
        int result = userMapper.updateLastLoginInfo(userId, loginIp);
        
        log.info("更新用户最后登录信息完成，用户ID：{}，结果：{}", userId, result > 0);
        return result > 0;
    }
}
